home *** CD-ROM | disk | FTP | other *** search
- /*
- MSAEScript.c
-
- Version 3.1
-
- Copyright © 1995 Apple Computer, Inc., all rights reserved.
-
- MenuScripter by Nigel Humphreys and Jon Lansdell
- AppleEvent to script extensions by Greg Sutton
- */
-
- #include <AppleScript.h>
- #include <Resources.h>
- #include <OSA.h>
- #include <AERegistry.h>
- #include <ASRegistry.h>
- #include <TextUtils.h>
-
- #ifndef THINK_C
- #include <PLStringFuncs.h>
- #endif
-
- #include "MSAEScript.h"
- #include "MSAppleEvents.h"
-
- extern ComponentInstance gScriptingComponent;
-
- #ifdef THINK_C
- extern pascal StringPtr PLstrcpy(StringPtr str1, StringPtr str2);
- extern pascal StringPtr PLstrcat(StringPtr str1, StringPtr str2);
- #endif
-
- short gAppVol;
- long gAppDir;
-
- OSAID gScript1ID;
- OSAID gScript2ID;
- // Script 3 targets a script application - it's script is not loaded
- OSAID gScript4ID;
- OSAID gScript5ID;
-
- // Variables to target script application
- ProcessSerialNumber gScriptAppPSN;
- AEDesc gScriptAppAddress;
-
- Str31 gScript1Name = "\pscript shift";
- Str31 gScript2Name = "\pscript datestring";
- Str31 gScript3Name = "\pscript topseeturvee";
- Str31 gScript4Name = "\pscript changecreator";
- Str31 gScript5Name = "\pscript get/set selection";
-
-
- // Use process manager to find the volume and directory of this application.
-
- pascal OSErr GetVolumeAndDirectory(void)
- {
- ProcessSerialNumber PSN;
- ProcessInfoRec info;
- Str31 name;
- FSSpec specRec;
- OSErr err;
-
- gAppVol = 0;
- gAppDir = 0;
-
- err = GetCurrentProcess(&PSN);
-
- if (err == noErr)
- {
- info.processName = name;
- info.processAppSpec = &specRec;
- err = GetProcessInformation(&PSN, &info);
-
- if (err == noErr)
- {
- gAppVol = specRec.vRefNum;
- gAppDir = specRec.parID;
- }
- }
-
- return(err);
- }
-
-
- // Launch an application into the background given an FSSpec
-
- pascal OSErr FSSpecLaunchApplication(const FSSpec *fileSpec, ProcessSerialNumber *PSN)
- {
- LaunchParamBlockRec launchRec;
- OSErr err;
-
- launchRec.launchBlockID = extendedBlock;
- launchRec.launchEPBLength = extendedBlockLen;
- launchRec.launchFileFlags = 0;
- launchRec.launchControlFlags = launchContinue + launchNoFileFlags + launchDontSwitch;
- launchRec.launchAppSpec = (FSSpecPtr)fileSpec;
- launchRec.launchAppParameters = nil;
-
- err = LaunchApplication(&launchRec);
-
- if (err == noErr)
- *PSN = launchRec.launchProcessSN;
-
- return(err);
- }
-
- // Set up the scripts we can send AppleEvents to them.
- // Launch the script application.
-
- pascal void SetUpScripts(void)
- {
- FSSpec fileSpec;
- OSErr err;
-
- fileSpec.vRefNum = gAppVol;
- fileSpec.parID = gAppDir;
-
- PLstrcpy(fileSpec.name,gScript1Name);
- LoadScriptFromFile(&fileSpec, &gScript1ID);
-
- PLstrcpy(fileSpec.name,gScript2Name);
- LoadScriptFromFile(&fileSpec, &gScript2ID);
-
- PLstrcpy(fileSpec.name,gScript3Name);
- err = FSSpecLaunchApplication(&fileSpec,&gScriptAppPSN);
- if (err == noErr)
- AECreateDesc(typeProcessSerialNumber,(Ptr)&gScriptAppPSN,
- sizeof(ProcessSerialNumber), &gScriptAppAddress);
- else
- gScriptAppAddress.dataHandle = NULL;
-
- PLstrcpy(fileSpec.name,gScript4Name);
- LoadScriptFromFile(&fileSpec, &gScript4ID);
-
- PLstrcpy(fileSpec.name,gScript5Name);
- LoadScriptFromFile(&fileSpec, &gScript5ID);
-
- }
-
- // Given a FileSpec open the resource fork and Load the first script
- // then release the resource and close the file.
- // The theScriptID will be set to kOSANullScript if any problems - so check against this for use.
-
- pascal OSErr LoadScriptFromFile(FSSpec *fileSpec, OSAID *theScriptID)
- {
- OSErr ignoreErr;
- Handle myScript;
- AEDesc myLoadScriptDesc;
- short fileRef;
- OSErr err;
-
- *theScriptID = kOSANullScript;
-
- fileRef = FSpOpenResFile(fileSpec, fsRdPerm);
- err = ResError();
-
- if (err == noErr)
- {
- myScript = Get1Resource(kOSAScriptResourceType, 128);
- if (myScript != NULL)
- {
- HLock(myScript);
-
- err = AECreateDesc(typeOSAGenericStorage,(Ptr)*myScript,
- GetHandleSize(myScript),&myLoadScriptDesc);
-
- HUnlock(myScript);
-
- if (err==noErr)
- {
- err = OSALoad(gScriptingComponent,&myLoadScriptDesc,
- kOSAModeNull,theScriptID);
- }
-
- ignoreErr = AEDisposeDesc(&myLoadScriptDesc);
- ReleaseResource(myScript);
- }
- CloseResFile(fileRef);
- }
-
- return(err);
- }
-
- // Store the scipt ID as a 'scpt' resource, ID 128, in file given.
-
- pascal OSErr StoreScriptToFile(FSSpec *fileSpec, OSAID theScriptID)
- {
- short fileRef;
- OSErr err;
-
- if (theScriptID == kOSANullScript)
- return(noErr);
-
- fileRef = FSpOpenResFile(fileSpec, fsWrPerm);
- err = ResError();
-
- if (err == noErr)
- {
- AEDesc scriptData = {typeNull,NULL};
-
- err = (OSErr)OSAStore(gScriptingComponent, theScriptID, typeOSAGenericStorage,
- kOSAModeNull, &scriptData);
-
- if (err == noErr)
- { // Write over current script
- Handle h = Get1Resource(kOSAScriptResourceType, 128);
- if (h)
- {
- RemoveResource(h); // Disposed of on UpdateResFile
- err = ResError();
- }
-
- if (err == noErr)
- {
- h = scriptData.dataHandle;
- HLock(h);
- HandToHand(&h);
- AddResource(h, typeOSAGenericStorage, 128, "\p");
- UpdateResFile(fileRef);
- HUnlock(h);
- }
-
- AEDisposeDesc(&scriptData);
- }
-
- CloseResFile(fileRef);
- }
-
- return(err);
- }
-
- // Quit the script application, store changes to scripts and dispose of scripts.
-
- pascal OSErr CleanUpAEScripts(void)
- {
- AppleEvent myAppleEvent = {typeNull,NULL},
- ignoreReply = {typeNull,NULL};
- FSSpec fileSpec;
- OSErr err;
-
- // Quit the script application we launched
- if (gScriptAppAddress.dataHandle)
- {
- err = AECreateAppleEvent(kCoreEventClass, kAEQuitApplication, &gScriptAppAddress,
- 0, 0, &myAppleEvent);
-
- if (err == noErr)
- err = AESend(&myAppleEvent, &ignoreReply, kAENoReply + kAEAlwaysInteract,
- kAENormalPriority, kAEDefaultTimeout, NULL, NULL);
-
- AEDisposeDesc(&myAppleEvent);
- }
-
- // Store the scripts used - this saves any changed properties and aliases
- fileSpec.vRefNum = gAppVol;
- fileSpec.parID = gAppDir;
-
- PLstrcpy(fileSpec.name,gScript1Name);
- StoreScriptToFile(&fileSpec, gScript1ID);
-
- PLstrcpy(fileSpec.name,gScript2Name);
- StoreScriptToFile(&fileSpec, gScript2ID);
-
- PLstrcpy(fileSpec.name,gScript4Name);
- StoreScriptToFile(&fileSpec, gScript4ID);
-
- PLstrcpy(fileSpec.name,gScript5Name);
- StoreScriptToFile(&fileSpec, gScript5ID);
-
- err = OSADispose(gScriptingComponent, gScript1ID);
- err = OSADispose(gScriptingComponent, gScript2ID);
- err = OSADispose(gScriptingComponent, gScript4ID);
- err = OSADispose(gScriptingComponent, gScript5ID);
-
- return(err);
- }
-
-
- // Calls a script subroutine that takes two window names or numbers.
- // If a window doesn't exist then it is created, one window is then
- // moved below the other.
- // Uses predefined label parameters.
- // on shift around winMove below winStay
-
- pascal OSErr ExecuteScript1(DPtr theDoc)
- {
- #pragma unused (theDoc)
-
- AppleEvent myAppleEvent = {typeNull,NULL},
- ignoreReply = {typeNull,NULL};
- AEDesc selfAddress;
- OSErr myErr;
- Str255 handlerName = "\pshift",
- below = "\pBelow",
- above = "\pAbove";
-
- if (gScript1ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return noErr;
-
- // Set up a subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Add the name of the subroutine
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&handlerName[1], handlerName[0]);
-
- // Add the first predefined label parameter
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASPrepositionAround, typeChar,
- (Ptr)&below[1], below[0]);
-
- // Add the second predefined label parameter
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASPrepositionBelow, typeChar,
- (Ptr)&above[1], above[0]);
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript1ID,
- kOSAModeAlwaysInteract, &ignoreReply);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(&ignoreReply);
-
- return(myErr);
- }
-
- // Calls a subroutine that returns the date and/or time depending
- // on parameters sent.
- // Uses subroutine defined label parameters.
- // on datestring given wDate:fDate, wTime:fTime
-
- pascal OSErr ExecuteScript2(DPtr theDoc)
- {
- #pragma unused (theDoc)
-
- AppleEvent myAppleEvent = {typeNull,NULL},
- myReply = {typeNull,NULL}; // Need to NULL for OSADoEvent() routine
- AEDesc selfAddress,
- textDesc;
- AEDescList paramList = {typeNull,NULL};
- OSErr myErr;
- Str255 pStr = "\pdatestring";
-
- if (gScript2ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return noErr;
-
- // Create an AppleScript subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Specify the routine by it's name
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- // Create list for user defined label parameters
- if (myErr == noErr)
- myErr = AECreateList(NULL, 0 , false, ¶mList);
-
- if (myErr == noErr)
- { // Make sure label name is in lower case
- PLstrcpy(pStr,"\pwdate");
- myErr = AEPutPtr(¶mList, 0 ,typeChar ,(Ptr)&pStr[1], pStr[0]);
- if (myErr == noErr) myErr = AEPutPtr(¶mList, 0, typeTrue , NULL, 0);
- }
-
- if (myErr == noErr)
- {
- PLstrcpy(pStr,"\pwtime");
- myErr = AEPutPtr(¶mList, 0 ,typeChar ,(Ptr)&pStr[1], pStr[0]);
- if (myErr == noErr) AEPutPtr(¶mList, 0, typeFalse , NULL, 0);
- }
-
- // Add list to AppleEvent
- if (myErr == noErr)
- myErr = AEPutParamDesc(&myAppleEvent, keyASUserRecordFields, ¶mList);
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript2ID,
- kOSAModeAlwaysInteract, &myReply);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(¶mList);
-
- if (myErr == noErr)
- myErr = GetTextDescFromReply(&myReply, &textDesc);
-
- if (myErr == noErr)
- myErr = SetSelection(&textDesc);
-
- AEDisposeDesc(&textDesc);
- AEDisposeDesc(&myReply);
-
- return(myErr);
- }
-
- // First of all gets the current selection. Then calls a script application
- // subroutine to twist the text in the selection. Finally it sets the selection
- // with the result.
- // Uses a positional parameter.
- // on topseeturvee(someText)
-
- pascal OSErr ExecuteScript3(DPtr theDoc)
- {
- #pragma unused (theDoc)
-
- AppleEvent myAppleEvent = {typeNull,NULL},
- myReply = {typeNull,NULL};
- AEDescList paramList = {typeNull,NULL},
- textDesc;
- OSErr myErr;
- Str255 pStr = "\ptopseeturvee";
-
- if (! gScriptAppAddress.dataHandle)
- return(noErr);
-
- // Get the current selection of the front window
- myErr = GetSelection(&textDesc);
-
- // Create a subroutine AppleEvent
- if (myErr == noErr)
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &gScriptAppAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Add the name of the subroutine
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- // Create positional parameter list
- if (myErr == noErr)
- myErr = AECreateList(NULL, 0 ,false, ¶mList);
-
- // Add textDesc as positional parameter
- if (myErr == noErr)
- myErr = AEPutDesc(¶mList, 0, &textDesc);
-
- // Add positional parameter list
- if (myErr == noErr)
- myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, ¶mList);
-
- if (myErr == noErr)
- myErr = AESend(&myAppleEvent, &myReply, kAEWaitReply + kAEAlwaysInteract,
- kAENormalPriority, kAEDefaultTimeout, gAEIdleUPP, NULL);
-
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(¶mList);
- // Dispose of textDesc before we get one in reply
- AEDisposeDesc(&textDesc);
-
- if (myErr == noErr)
- myErr = GetTextDescFromReply(&myReply, &textDesc);
-
- if (myErr == noErr)
- {
- myErr = SetSelection(&textDesc);
- AEDisposeDesc(&textDesc);
- }
-
- AEDisposeDesc(&myReply);
-
- return(myErr);
- }
-
- // Calls script subroutine that changes a given file's creator
- // to the creator specified.
- // Uses direct and predefined label parameters.
- // on changecreator of aSpec into aCreator
-
- pascal OSErr ExecuteScript4(DPtr theDoc)
- {
- AppleEvent myAppleEvent = {typeNull,NULL},
- ignoreReply = {typeNull,NULL};
- AEDesc selfAddress;
- AEDescList paramList = {typeNull,NULL};
- OSErr myErr;
- Str255 pStr = "\pchangecreator";
-
- if (gScript4ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return myErr;
-
- // Create a subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Add the name of the subroutine
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- // Add the direct parameter
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyDirectObject, typeFSS,
- (Ptr)&(theDoc->theFSSpec), sizeof(FSSpec));
-
- // Add the subroutine parameter label
- if (myErr == noErr)
- {
- PLstrcpy(pStr, "\pToyS");
- myErr = AEPutParamPtr(&myAppleEvent, keyASPrepositionInto, typeChar,
- (Ptr)&pStr[1], pStr[0]);
- }
-
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript4ID,
- kOSAModeAlwaysInteract, &ignoreReply);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(&ignoreReply);
-
- return(myErr);
- }
-
-
- // Calls script subroutine to get this application's selection.
- // Uses no parameters except for subroutine name.
- // on getselection()
-
- pascal OSErr GetSelection(AEDesc *textDesc)
- {
- AppleEvent myAppleEvent = {typeNull,NULL},
- myReply = {typeNull,NULL};
- AEDesc selfAddress;
- OSErr myErr;
- Str255 pStr = "\pgetselection";
-
- if (gScript5ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return myErr;
-
- // Create an AppleScript subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Specify the routine by it's name
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript5ID,
- kOSAModeAlwaysInteract, &myReply);
-
- myErr = GetTextDescFromReply(&myReply, textDesc);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(&myReply);
-
- return(myErr);
- }
-
-
- // Calls script subroutine to set this application's selection.
- // Uses a positional parameter.
- // setselection(aString)
-
- pascal OSErr SetSelection(AEDesc *textDesc)
- {
- AppleEvent myAppleEvent = {typeNull,NULL},
- myReply = {typeNull,NULL};
- AEDesc selfAddress;
- AEDescList paramList = {typeNull,NULL};
- OSErr myErr;
- Str255 pStr = "\psetselection";
-
- if (gScript5ID == kOSANullScript)
- return(noErr);
-
- myErr = MakeSelfAddress(&selfAddress);
- if (myErr != noErr) return myErr;
-
- // Create an AppleScript subroutine AppleEvent
- myErr = AECreateAppleEvent(kASAppleScriptSuite, kASSubroutineEvent, &selfAddress,
- kAutoGenerateReturnID, kAnyTransactionID, &myAppleEvent);
-
- // Specify the routine by it's name
- if (myErr == noErr)
- myErr = AEPutParamPtr(&myAppleEvent, keyASSubroutineName, typeChar,
- (Ptr)&pStr[1], pStr[0]);
-
- // Create positional parameter list
- if (myErr == noErr)
- myErr = AECreateList(NULL, 0 ,false, ¶mList);
-
- // Add textDesc as positional parameter
- if (myErr == noErr)
- myErr = AEPutDesc(¶mList, 0, textDesc);
-
- // Add positional parameter list
- if (myErr == noErr)
- myErr = AEPutParamDesc(&myAppleEvent, keyDirectObject, ¶mList);
-
- if (myErr == noErr)
- myErr = OSADoEvent(gScriptingComponent, &myAppleEvent, gScript5ID,
- kOSAModeAlwaysInteract, &myReply);
-
- AEDisposeDesc(&selfAddress);
- AEDisposeDesc(&myAppleEvent);
- AEDisposeDesc(¶mList);
- AEDisposeDesc(&myReply);
-
- return(myErr);
- }
-
- // Takes a reply and tries to get a text descriptor from it.
-
- pascal OSErr GetTextDescFromReply(AEDesc *aReply, AEDesc *textDesc)
- {
- OSErr myErr;
-
- textDesc->descriptorType = typeNull;
- textDesc->dataHandle = NULL;
-
- myErr = AEGetParamDesc(aReply, keyAEResult, typeChar, textDesc);
-
- return(myErr);
- }
-
-
- pascal void EnableAEScriptItems(Boolean fEnable)
- {
- if (fEnable && kOSANullScript != gScript1ID)
- EnableItem(myMenus[scriptM], cScript1);
- else
- DisableItem(myMenus[scriptM], cScript1);
- if (fEnable && kOSANullScript != gScript2ID)
- EnableItem(myMenus[scriptM], cScript2);
- else
- DisableItem(myMenus[scriptM], cScript2);
- if (fEnable && gScriptAppAddress.dataHandle)
- EnableItem(myMenus[scriptM], cScript3);
- else
- DisableItem(myMenus[scriptM], cScript3);
- if (fEnable && kOSANullScript != gScript4ID)
- EnableItem(myMenus[scriptM], cScript4);
- else
- DisableItem(myMenus[scriptM], cScript4);
- }